/**
 * @file      watchdog_api.c
 * @brief     看门狗API接口
 * @version   1.0
 * @date      2023.12.26
 *
 * @copyright Copyright (c) 2018 UCchip Technology Co.,Ltd. All rights reserved.
 *
 * Change Logs:
 * Date          Author       Notes
 * 2023.12.26    jrhe         the first version
 *
 */
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include "uc_log.h"

#ifdef RT_USING_WDT

#include "watchdog_app.h"

#define WDT_DEVICE_NAME "wdt"

static rt_device_t wdg_dev = RT_NULL;

static void idle_watchdog_hook(void)
{
    if (RT_NULL == wdg_dev)
    {
        return;
    }
    rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_KEEPALIVE, NULL);
}

int watchdog_app_init(void)
{
    rt_err_t ret = RT_EOK;
    rt_uint32_t timeout = WATCHDOG_TIMEOUT_SEC;

    wdg_dev = rt_device_find(WDT_DEVICE_NAME);
    if (RT_NULL == wdg_dev)
    {
        TRACE_E("find %s failed!\n", WDT_DEVICE_NAME);
        return RT_ERROR;
    }

    ret = rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, &timeout);
    if (ret != RT_EOK)
    {
        TRACE_E("set %s timeout failed!\n", WDT_DEVICE_NAME);
        return RT_ERROR;
    }
    // 设置空闲钩子回调
    rt_thread_idle_sethook(idle_watchdog_hook);

    return ret;
}

int watchdog_app_disable(void)
{
    rt_err_t ret = RT_EOK;

    if (RT_NULL == wdg_dev)
    {
        TRACE_E("watchdog disable err,name %s\n", WDT_DEVICE_NAME);
        return 1;
    }

    ret = rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_STOP, RT_NULL);
    if (ret != RT_EOK)
    {
        TRACE_E("stop %s failed!\n", WDT_DEVICE_NAME);
        return -RT_ERROR;
    }
    return ret;
}

int watchdog_app_enable(void)
{
    rt_err_t ret = RT_EOK;

    if (RT_NULL == wdg_dev)
    {
        TRACE_E("watchdog enable err,name %s\n", WDT_DEVICE_NAME);
        return 1;
    }
    ret = rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_START, RT_NULL);
    if (ret != RT_EOK)
    {
        TRACE_E("start %s failed!\n", WDT_DEVICE_NAME);
        return -RT_ERROR;
    }

    return ret;
}

void watchdog_app_close(void)
{
    watchdog_app_disable();
    rt_thread_idle_delhook(idle_watchdog_hook);
}

void watchdog_app_feed(void)
{
    idle_watchdog_hook();
}

void watchdog_reboot(void)
{
    rt_uint32_t timeout = 1;
    rt_err_t ret = RT_EOK;

    if (NULL == wdg_dev)
    {
        wdg_dev = rt_device_find(WDT_DEVICE_NAME);
    }
    if (!wdg_dev)
    {
        TRACE_E("find %s failed!\n", WDT_DEVICE_NAME);
        return;
    }

    ret = rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, &timeout);
    if (ret != RT_EOK)
    {
        TRACE_E("set %s timeout failed!\n", WDT_DEVICE_NAME);
        return;
    }
    watchdog_app_enable();

    rt_thread_mdelay(500);

    while (1)
        ;
}

#endif